Python OpenCV 霍夫(Hough Transform)直线变换检测应用 | 您所在的位置:网站首页 › python opencv 霍夫变换 › Python OpenCV 霍夫(Hough Transform)直线变换检测应用 |
Python OpenCV 365 天学习计划,与橡皮擦一起进入图像领域吧。本篇博客是这个系列的第 34 篇。 Python OpenCV 基础知识铺垫 霍夫直线变换函数原型 概率霍夫变换(Probabilistic Hough Transform) 橡皮擦的小节 基础知识铺垫上篇博客 咱们一起学习了霍夫直线检测的原理,本篇就从应用层对其进行学习啦。 学习了原理之后,在查看函数原型,发现确实简单了许多。 霍夫直线变换函数原型在 OpenCV 中提供了两个霍夫直线检测的函数,一个是标准霍夫变换,另一个是概率霍夫变换。 先学习一下标准霍夫变换吧,该变化方式也叫做多尺度霍夫变换。 该方法使用的函数是 cv2.HoughLines,函数原型如下 lines = cv2.HoughLines(image, rho, theta, threshold[, lines[, srn[, stn[, min_theta[, max_theta]]]]]) 1参数说明: image:输入 8 位灰度图像; rho:生成极坐标时像素扫描步长; theta:生成极坐标时候的角度步长; threshold:阈值; lines:返回值,极坐标表示的直线; sen:是否应用多尺度的霍夫变换,如果不是设置 0 表示经典霍夫变换; stn:是否应用多尺度的霍夫变换,如果不是设置 0 表示经典霍夫变换; min_theta:角度扫描范围最小值; max_theta:角度扫描范围最大值。该函数的返回值就是上篇博客提及的 ( θ,ρ ),其中 ρ 的单位是像素, θ 的单位是弧度。 既然是直线检测,那我们先把图像的边缘检测出来,通过之前学习的知识即可,加入滑动条,方便调参。 import cv2 as cv import numpy as np src = cv.imread("./331.jpg") gray_img = cv.cvtColor(src, cv.COLOR_BGR2GRAY) def nothing(): pass cv.namedWindow("bar") cv.createTrackbar("threshold1", "bar", 0, 255, nothing) cv.createTrackbar("threshold2", "bar", 0, 255, nothing) dst = cv.equalizeHist(gray_img) # 高斯滤波降噪 gaussian = cv.GaussianBlur(dst, (9, 9), 0) cv.imshow("gaussian", gaussian) while True: threshold1 = cv.getTrackbarPos("threshold1", "bar") threshold2 = cv.getTrackbarPos("threshold2", "bar") # 边缘检测 edges = cv.Canny(gaussian, threshold1, threshold2) cv.imshow("edges", edges) if cv.waitKey(1) & 0xFF == 27: break cv.destroyAllWindows() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28运行代码之后,获取到的边缘如下,下面就可以对直线进行获取了,通过cv2.HoughLines函数。
上述代码中,相关说明如下: 第二个参数为半径的步长,第三个参数为每次偏转的角度,即我们提及的 ρ 和 θ; rho 参数为极径 r, 以像素值为单位, 本案例使用 1 像素; theta参数极角 θ 以弧度为单位,本案例使用 1 度 (即 np.pi/180); threshold 参数随便给的。还有计算具体坐标用到的公式其实是这样的:(p,q) = (rcosθ,rsinθ) 运行效果基本满意,达到预期。 概率霍夫变换是一种概率直线检测,它是针对于上文标准霍夫检测的优化,核心点是采取概率挑选机制,选取一些点出来进行计算,相当于降采样。 函数名称与原型如下: lines = cv2.HoughLinesP(image, rho, theta, threshold[, lines[, minLineLength[, maxLineGap]]]) 1参数说明: src:输入 8-bit 的灰度图像; rho:像素为单位的距离精度,double 类型的,推荐用 1.0; theta:以弧度为单位的角度精度,推荐用 numpy.pi/180; threshold:阈值; lines:输出的极坐标来表示直线; minLineLength:最短长度阈值,比这个长度短的线会被排除; maxLineGap:最大间隔,如果小于此值,这两条直线就被看成是一条直线。该函数还有一个优点,返回值是一条条线段,不用我们在进行转换了 修改上文代码如下,参数赋值部分直接写的,你可以自由修改,也可以通过滑动条调参: import cv2 as cv import numpy as np src = cv.imread("./331.jpg") gray_img = cv.cvtColor(src, cv.COLOR_BGR2GRAY) dst = cv.equalizeHist(gray_img) # 高斯滤波降噪 gaussian = cv.GaussianBlur(dst, (9, 9), 0) # cv.imshow("gaussian", gaussian) # 边缘检测 edges = cv.Canny(gaussian, 70, 150) cv.imshow("edges", edges) lines = cv.HoughLinesP(edges, 1.0, np.pi/180, 100, minLineLength=100, maxLineGap=6) print(type(lines)) for line in lines: x1, y1, x2, y2 = line[0] cv.line(src, (x1, y1), (x2, y2), (0, 255, 0), 2) cv.imshow("src", src) cv.waitKey() cv.destroyAllWindows() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25运行代码之后,可以获取到相应的线段。 OpenCV 的文章阶段性的难度开始爬升了,有些地方概念还是有点模糊,需要学习的地方太多了,一起加油吧 希望今天的 1 个小时(今天内容有点多,不一定可以看完),你有所收获,我们下篇博客见~ 相关阅读 技术专栏 Python 爬虫 100 例教程,超棒的爬虫教程,立即订阅吧 Python 爬虫小课,精彩 9 讲今天是持续写作的第 74 / 100 天。 如果你有想要交流的想法、技术,欢迎在评论区留言。 如果你想跟博主建立亲密关系,可以关注同名公众号 梦想橡皮擦,近距离接触一个逗趣的互联网高级网虫。 博主 ID:梦想橡皮擦,希望大家点赞、评论、收藏。 文章来源: dream.blog.csdn.net,作者:梦想橡皮擦,版权归原作者所有,如需转载,请联系作者。 原文链接:dream.blog.csdn.net/article/details/113670582 |
CopyRight 2018-2019 实验室设备网 版权所有 |